AWS ParallelCluster に Mountpoint for Amazon S3 を使って S3 バケットをマウントする方法
AWS ParallelCluster に Mountpoint for Amazon S3 を利用して、S3 バケットをマウントしたクラスター環境を構築手順を紹介します。
ヘッドノード、コンピュートノードから直接 S3 バケットのデータを取得できます。大容量のデータを読み取ることの多い機械学習、ゲノム解析(リファレンスゲノムなど)のワークロードで ParallelCluster を利用する場合は本構成もご検討ください。
Inventory icons created by Freepik - Flaticon
S3 バケットに保存してあるファイルをパス指定(例: /mnt/s3
)で直接ファイルアクセスできるようになった点が大きな変更点です。
Mountpoint for Amazon S3 でマウントした S3 バケットに対しての書き込み処理は注意が必要です。多くのケースは図の様に EBS や、EFS などのブロックストレージに一度書き出すことになります。最終的なデータ保存先として S3 へコピーや、移動するときの書き込み処理はあまり心配ありません。
2023/10/8追記Ubuntu 22.04 を利用する場合は以下のブログもご参照ください。
設定の流れ
事前準備作業が地味に多いです。S3 バケットと IAM ポリシー、マウントスクリプトは一度作成すれば、他クラスター間で使いまわしできます。用途別に S3 バケットを分けたい場合は同じ手順を踏む必要はあります。
- マウント用の S3 バケット、IAM ポリシーを事前に作成する
- カスタムブートストラップアクションで実行する S3 マウントスクリプトを作成し、S3 に保存
- クラスターのコンフィグに IAM ポリシーの付与と、カスタムブートストラップアクション設定を追加
- クラスターをデプロイ(
pclsuter create-cluster
の実行) - ヘッドノードに手動で S3 自動マウント用の設定追加
検証環境
OS は Ubuntu 20.04 LTS の AWS ParallelCluster 3.6.1 環境で検証しています。mount-s3 コマンドのバージョンは1.0.0
です。
S3 をマウントするための準備
ParallelCluster に S3 バケットをマウントするために以下のリソースを事前に作成します。
- マウント対象となる S3 バケット
- ヘッドノード、コンピュートノードに必要な IAM ポリシー
CloudFormation テンプレート
必要なリソースは以下の CloudFormation テンプレートから作成できます。
AWSTemplateFormatVersion: "2010-09-09" Description: S3 Bucket and IAM Policy for Mountpoint for S3 Parameters: ProjectName: Description: Project Name Type: String Default: unnamed Environment: Description: Environment Type: String Default: dev AllowedValues: - prod - dev S3BucketName: Description: Bucket name Type: String Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Common Settings Parameters: - ProjectName - Environment Resources: # ------------------------------------------------------------------------------------ # # S3 # ------------------------------------------------------------------------------------ # S3Bucket: Type: AWS::S3::Bucket Properties: BucketName: !Sub ${ProjectName}-${Environment}-${S3BucketName}-${AWS::AccountId} OwnershipControls: Rules: - ObjectOwnership: "BucketOwnerEnforced" PublicAccessBlockConfiguration: BlockPublicAcls: True BlockPublicPolicy: True IgnorePublicAcls: True RestrictPublicBuckets: True VersioningConfiguration: Status: Enabled BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: "AES256" BucketKeyEnabled: false LifecycleConfiguration: Rules: - Id: AbortIncompleteMultipartUpload AbortIncompleteMultipartUpload: DaysAfterInitiation: 7 Status: "Enabled" - Id: NoncurrentVersionExpiration NoncurrentVersionExpiration: NoncurrentDays: 14 Status: Enabled - Id: IntelligentTiering Transitions: - TransitionInDays: 7 StorageClass: INTELLIGENT_TIERING Status: Enabled # ------------------------------------------------------------------------------------ # # IAM Policy # ------------------------------------------------------------------------------------ # S3AccessPolicy: Type: "AWS::IAM::ManagedPolicy" Properties: ManagedPolicyName: !Sub ${ProjectName}-${Environment}-AllowMountpointForS3 Path: "/" PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: - "s3:ListBucket" Resource: - !Sub arn:aws:s3:::${ProjectName}-${Environment}-${S3BucketName}-${AWS::AccountId} - Effect: "Allow" Action: - "s3:GetObject" - "s3:PutObject" - "s3:AbortMultipartUpload" - "s3:DeleteObject" Resource: - !Sub arn:aws:s3:::${ProjectName}-${Environment}-${S3BucketName}-${AWS::AccountId}/* Outputs: ExportIAMPolicy: Value: !Ref "S3AccessPolicy" Export: Name: !Sub "${AWS::StackName}-S3AccessPolicy" ExportS3Bucket: Value: !Ref "S3Bucket" Export: Name: !Sub "${AWS::StackName}-S3BucketARN"
パラメータ入力
任意の名前を入力してください。
参考までに上記のパラメータで生成したときのリソース名は以下になります。
S3 バケットの設定内容の説明
暗号化、バージョニング有効化などの基本的な設定に加えて HPC ワークロードを考慮して以下の設定を追加しています。
- S3 Inteligent-Tiering ストレージクラスへ 7 日後にデータ移動
- ストレージコスト自動最適化の意図
- S3 から削除したファイルは 14 日後に完全に削除
- お好みで保持日数の変更してください
- Amazon S3 ライフサイクルで世代管理を実現する「バージョン数の保持」を試してみた | DevelopersIO
- マルチパートアップロードの残骸 7 日後に削除
- Mountpoint for Amazon S3 でマルチパートアップロードが利用されているため、不要なファイルの定期削除
S3 バケット名はユニークな名前にするために AWS アカウント ID を末尾に自動的に付与しています。命名規則はお好みで変更してください。
S3Bucket: Type: AWS::S3::Bucket Properties: BucketName: !Sub ${ProjectName}-${Environment}-${S3BucketName}-${AWS::AccountId}
IAM ポリシーの設定内容の説明
CloudFormation で作成したマウント対象の S3 バケットへのみ最低限必要な権限をもたせる IAM ポリシーが CloudFormation テンプレートから作成されます。ParallelCluster からマウントした S3 バケットに対してファイルの読み書きができるようにs3:DeleteObject
の権限を持たせています。
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::[CloudFromation で作成した S3 バケット名が自動入力されています]" ], "Effect": "Allow" }, { "Action": [ "s3:GetObject", "s3:PutObject", "s3:AbortMultipartUpload", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::[CloudFormation で作成した S3 バケット名が自動入力されています]/*" ], "Effect": "Allow" } ] }
カスタムブートストラップアクションの準備
コンピュートノード起動時に S3 バケットをマウントするスクリプト作成し、カスタムブートストラップ用の S3 バケットに保存します。ここでは S3 バケットをマウントするのに必要なスクリプトを紹介します。
mount-s3.deb
パッケージをダウンロードしてインストール- S3 バケットのマウント先のパスを
/mnt/s3
ディレクトリを作成 mount-s3
コマンドで/mnt/s3
へ S3 バケットをマウント
CloudFormation で作成した S3 バケット名に置き換えてスクリプトをご利用ください。
#! /bin/bash wget -P /tmp https://s3.amazonaws.com/mountpoint-s3-release/latest/x86_64/mount-s3.deb sudo apt-get install /tmp/mount-s3.deb -y sudo mkdir /mnt/s3 sudo mount-s3 --allow-delete --allow-other [要手動入力: CloudFormation で作成した S3バケット名] /mnt/s3/
カスタムブートストラップ用の S3 バケットの作成は省略します。適当な S3 バケットを作成してスクリプトを保存してください。
クラスターコンフィグ作成
S3 バケットをマウントするのに必要な追加設定について説明します。
マウントする S3 バケットへのアクセス権追加
ヘッドノードと、キュー毎のコンピュートノードに IAM ポリシーを追加します。IAM ポリシー名は CloudFormation テンプレートで作成されています。リソース名を確認し ARN を入力してください。
個々の環境によってアカウント ID、CloudFormation に入力したパラメータの値によって IAM ポリシー名が異なります。ご自身の環境に合わせて修正してください。
# ヘッドノード Iam: AdditionalIamPolicies: - Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore - Policy: arn:aws:iam::123456789012:policy/hpc-dev-AllowMountpointForS3 --- 略 --- # コンピュートノード(キューの数分だけ設定が必要) Iam: AdditionalIamPolicies: - Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore - Policy: arn:aws:iam::123456789012:policy/hpc-dev-AllowMountpointForS3
コンピュートノード起動時に S3 バケットをマウントするスクリプト実行
カスタムブートストラップ用の S3 バケットに保存したスクリプトのパスを入力します。
個々の環境によってスクリプト保存先の S3 バケット名、パス、スクリプト名が異なります。ご自身の環境に合わせて修正してください。
# コンピュートノード(キューの数分だけ設定が必要) CustomActions: OnNodeConfigured: Script: s3://hpc-dev-postinstall-files/mount-moutpoint-for-s3/mount.sh
ヘッドノードへのカスタムブートストラップによるマウント設定は不要です。ヘッドノードの設定を自動化する上手い方法が思いつかなかったため、ヘッドノード起動後にログインして手動でマウント設定します。
既存の実行スクリプトが指定されている場合
ParallelCluster 3.6.0 のアップデートで、複数のスクリプトを列挙して実行できるようになりました。v3.6.0 以降であれば、既存のスクリプトがある場合はSequence:
を追加し実行スクリプトを列挙すれば既存のスクリプトをいじることなく新たな処理を追加できます。
OnNodeConfigured: # Script URLs. The scripts are run in the same order as listed in the configuration, after all the bootstrap scripts are run Sequence: - Script1: s3://bucket-name/on-node-configured1.sh Args: - arg1 - Script2: s3://bucket-name/on-node-configured2.sh Args: - arg1
Custom bootstrap actions - AWS ParallelCluster
カスタムブートストラップ用の S3 バケットへのアクセス権追加
カスタムブートストラップ用の S3 バケットに保存したスクリプトにアクセスできる権限が別途必要になります。
# コンピュートノード(キューの数分だけ設定が必要) S3Access: - BucketName: hpc-dev-postinstall-files EnableWriteAccess: false
コンフィグ全文
検証用のクラスターを構築したコンフィグです。設定内容の参考にご覧ください。
Region: ap-northeast-1 Image: Os: ubuntu2004 Tags: - Key: Name Value: MountS3Cluster # ---------------------------------------------------------------- # Head Node Settings # ---------------------------------------------------------------- HeadNode: InstanceType: t3.micro Networking: ElasticIp: false SubnetId: subnet-035be95eeaa091603 Ssh: KeyName: sandbox-key LocalStorage: RootVolume: Size: 35 Encrypted: true VolumeType: gp3 Iops: 3000 Throughput: 125 Iam: AdditionalIamPolicies: - Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore - Policy: arn:aws:iam::123456789012:policy/hpc-dev-AllowMountpointForS3 S3Access: - BucketName: hpc-dev-postinstall-files EnableWriteAccess: false # ---------------------------------------------------------------- # Compute Node Settings # ---------------------------------------------------------------- Scheduling: Scheduler: slurm SlurmSettings: ScaledownIdletime: 5 SlurmQueues: # ------ Compute 1 ------ - Name: queue1 ComputeResources: - Name: queue1 Instances: - InstanceType: c6i.large - InstanceType: m6i.large MinCount: 0 MaxCount: 10 DisableSimultaneousMultithreading: true ComputeSettings: LocalStorage: RootVolume: Size: 35 Encrypted: true VolumeType: gp3 Iops: 3000 Throughput: 125 CapacityType: SPOT AllocationStrategy: lowest-price Networking: SubnetIds: - subnet-035be95eeaa091603 PlacementGroup: Enabled: false CustomActions: OnNodeConfigured: Script: s3://hpc-dev-postinstall-files/mount-moutpoint-for-s3/mount.sh Iam: AdditionalIamPolicies: - Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore - Policy: arn:aws:iam::123456789012:policy/hpc-dev-AllowMountpointForS3 S3Access: - BucketName: hpc-dev-postinstall-files EnableWriteAccess: false # ---------------------------------------------------------------- # Shared Storage Settings # ---------------------------------------------------------------- SharedStorage: - MountDir: /mnt/efs-1zone Name: efs-1zone StorageType: Efs EfsSettings: FileSystemId: fs-0f1158ade79354809 # ---------------------------------------------------------------- # Other Settings # ---------------------------------------------------------------- Monitoring: Logs: CloudWatch: Enabled: true RetentionInDays: 180 DeletionPolicy: "Delete" Dashboards: CloudWatch: Enabled: false
クラスターデプロイ後の設定
pcluster create-cluster
コマンドでクラスターをデプロイ後に必要な設定です。
ヘッドノードに S3 バケットを自動マウント設定追加
コンピュートノードはカスタムブートストラップアクションにより、コンピュートノードが起動時にマウント処理が走ります。ヘッドノードは手動で自動マウント設定を入れます。
マウント先のディレクトリを作成します。
sudo mkdir /mnt/s3
S3 バケットは専用のmount-s3
コマンドでマウントするのですが fstab のマウント処理はサポートしていません。そのため、ヘッドノード起動時になにかしらの方法でmount-s3
コマンドを実行する必要があります。
crontab を利用して起動時に任意のコマンドを一度実行する例です。一行書き加えれば良いだけで手軽なので今ところ私は採用しています。
@reboot sudo mount-s3 --allow-delete --allow-other [要手動入力: CloudFormation で作成した S3バケット名] /mnt/s3
以上でクラスターの設定は完了です。
まとめ
カスタムブートストラップアクションで S3 をマウントするスクリプトを実行することが肝です。そのための事前準備が多少必要でした。
- マウント用の S3 バケット、IAM ポリシーを事前に作成する
- カスタムブートストラップアクションで実行する S3 マウントスクリプトを作成し、S3 に保存
- クラスターのコンフィグに IAM ポリシーの付与と、カスタムブートストラップアクション設定を追加
- クラスターをデプロイ(
pclsuter create-cluster
の実行) - ヘッドノードに手動で S3 自動マウント用の設定追加
おわりに
ParallelCluster の設定手順のみの紹介となりました。アプリケーションの動作検証など時間あるときに試して結果を共有したいと思います。 なにがともあれ、クラスターに S3 バケットを直接マウントできることでファイルの読み込みに関しては大きく運用フローを改善できそうな大きなアップデートでした。